Passed
Pull Request — master (#141)
by Mathieu
07:44
created

AddEventCommandHandler.execute   A

Complexity

Conditions 4

Size

Total Lines 38
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 38
rs 9.112
c 0
b 0
f 0
cc 4
1
import { CommandHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { AddEventCommand } from './AddEventCommand';
4
import { ITaskRepository } from 'src/Domain/Task/Repository/ITaskRepository';
5
import { IProjectRepository } from 'src/Domain/Project/Repository/IProjectRepository';
6
import { IEventRepository } from 'src/Domain/FairCalendar/Repository/IEventRepository';
7
import { IsMaximumTimeSpentReached } from 'src/Domain/FairCalendar/Specification/IsMaximumTimeSpentReached';
8
import { Event, EventType } from 'src/Domain/FairCalendar/Event.entity';
9
import { IDateUtils } from 'src/Application/IDateUtils';
10
import { ProjectOrTaskMissingException } from 'src/Domain/FairCalendar/Exception/ProjectOrTaskMissingException';
11
import { AbstractProjectAndTaskGetter } from './AbstractProjectAndTaskGetter';
12
import { NoDateDuringThisPeriodException } from 'src/Domain/FairCalendar/Exception/NoDateDuringThisPeriodException';
13
import { AddEventsView } from '../View/AddEventsView';
14
15
@CommandHandler(AddEventCommand)
16
export class AddEventCommandHandler extends AbstractProjectAndTaskGetter {
17
  constructor(
18
    @Inject('ITaskRepository') taskRepository: ITaskRepository,
19
    @Inject('IProjectRepository') projectRepository: IProjectRepository,
20
    @Inject('IEventRepository')
21
    private readonly eventRepository: IEventRepository,
22
    @Inject('IDateUtils')
23
    private readonly dateUtils: IDateUtils,
24
    private readonly isMaximumTimeSpentReached: IsMaximumTimeSpentReached
25
  ) {
26
    super(taskRepository, projectRepository);
27
  }
28
29
  public async execute(command: AddEventCommand): Promise<AddEventsView> {
30
    const {type, startDate, endDate, projectId, taskId, summary, time, user} = command;
31
    const errors: string[] = [];
32
33
    if (type === EventType.MISSION && (!projectId || !taskId)) {
34
      throw new ProjectOrTaskMissingException();
35
    }
36
37
    const days = this.getDays(startDate, endDate);
38
39
    const [project, task] = await Promise.all([
40
      this.getProject(projectId),
41
      this.getTask(taskId)
42
    ]);
43
44
    for (const day of days) {
45
      const date = this.dateUtils.format(day, 'y-MM-dd');
46
      const event = new Event(
47
        type,
48
        user,
49
        time,
50
        date,
51
        project,
52
        task,
53
        summary
54
      );
55
56
      if (true === (await this.isMaximumTimeSpentReached.isSatisfiedBy(event))) {
57
        errors.push(date);
58
59
        continue;
60
      }
61
62
      this.eventRepository.save(event);
63
    }
64
65
    return new AddEventsView(errors);
66
  }
67
68
  private getDays(startDate: Date, endDate: Date): Date[] {
69
    const days = this.dateUtils.getWorkedDaysDuringAPeriod(startDate, endDate);
70
71
    if (0 === days.length) {
72
      throw new NoDateDuringThisPeriodException();
73
    }
74
75
    return days;
76
  }
77
}
78